﻿using Nop.Admin.Models.Media;
using Nop.Core.Domain.Media;
using Nop.Services.Configuration;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Security;
using Nop.Services.Stores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework;
using Nop.Core;
using Nop.Core.Domain.Common;
using Telerik.Web.Mvc;

//TODO: refine the whole controller for performance and so on.
using Telerik.Web.Mvc.UI;

namespace Nop.Admin.Controllers
{
    [AdminAuthorize]
    public partial class MediaController : BaseNopController
    {
        #region Fields

        private readonly ILanguageService _languageService;
        private readonly ILocalizedEntityService _localizedEntityService;
        private readonly IPictureDisplayService _pictureDisplayService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly ILocalizationService _localizationService;
        private readonly ISettingService _settingService;
        private readonly IPermissionService _permissionService;
        private readonly AdminAreaSettings _adminAreaSettings;
        private readonly IWorkContext _workContext;
        private readonly IStoreService _storeService;
        private readonly IPictureService _pictureService;

        #endregion

        #region Ctor

        public MediaController(
            ILanguageService languageService,
            ILocalizedEntityService localizedEntityService,
            IPictureDisplayService pictureDisplayService,
            ICustomerActivityService customerActivityService,
            ILocalizationService localizationService,
            ISettingService settingService,
            IPermissionService permissionService,
            AdminAreaSettings adminAreaSettings,
            IWorkContext workContext,
            IStoreService storeService,
            IPictureService pictureService
            )
        {
            _languageService = languageService;
            _localizedEntityService = localizedEntityService;
            _pictureDisplayService = pictureDisplayService;
            _customerActivityService = customerActivityService;
            _localizationService = localizationService;
            _settingService = settingService;
            _permissionService = permissionService;
            _adminAreaSettings = adminAreaSettings;
            _workContext = workContext;
            _storeService = storeService;
            _pictureService = pictureService;
        }

        #endregion

        #region Slideshow

        public ActionResult ListSlideshows()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSlideshows))
                return AccessDeniedView();

            int curManagedStoreId = _permissionService.GetAuthorizedStore(StandardPermissionProvider.ManageSlideshows);
            if (curManagedStoreId == 0)
            {
                return AccessDeniedView();
            }

            var model = new SlideshowListModel();

            //stores
            model.SearchStoreId = curManagedStoreId;
            var managedStore = _workContext.CurrentCustomer.ManagedStore;
            model.SearchStore = managedStore != null ? managedStore.Name : null;
            List<SlideshowModel> ssModels = new List<SlideshowModel>();
            if (curManagedStoreId != 1)
            {
                if (model.SearchStore != null)
                {
                    ssModels = _pictureDisplayService.GetSlideshowsByTypeAndContentCategory(null, "Store", model.SearchStoreId)
                    .Select(ss =>
                    {
                        var slideshowModel = ss.ToModel();
                        slideshowModel.CollectionSystemName =
                            _pictureDisplayService.GetPictureLinkCollectionById(ss.PictureLinkCollectionId).SystemName;
                        return slideshowModel;
                    })
                    .ToList();
                }
            }
            else
            {
                ssModels = _pictureDisplayService.GetAllSlideshows()
                    .Select(ss =>
                    {
                        var slideshowModel = ss.ToModel();
                        slideshowModel.CollectionSystemName =
                            _pictureDisplayService.GetPictureLinkCollectionById(ss.PictureLinkCollectionId).SystemName;
                        return slideshowModel;
                    })
                    .ToList();
            }

            if (model.PicturelinkCollections.Count == 0)
            {
                var collections = _pictureDisplayService.GetAllPictureLinkCollections().ToList();
                collections.ForEach(c =>
                    model.PicturelinkCollections.Add(
                    new SelectListItem()
                    {
                        Text = c.SystemName,
                        Value = c.Id.ToString(),
                        Selected = model.CollectionId == c.Id
                    }));
            }

            if (model.AddPictureModel == null)
                model.AddPictureModel = new PictureLinkModel();

            model.Slideshows = new GridModel<SlideshowModel>
            {
                Data = ssModels,
                Total = ssModels.Count
            };

            return View(model);
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult ListSlideshows(GridCommand command, SlideshowListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSlideshows))
                return AccessDeniedView();

            int curManagedStoreId = _permissionService.GetAuthorizedStore(StandardPermissionProvider.ManageSlideshows);
            if (curManagedStoreId == 0 || (curManagedStoreId != 1 && curManagedStoreId != model.SearchStoreId))
            {
                return AccessDeniedView();
            }

            List<SlideshowModel> ssModels = new List<SlideshowModel>();
            if (model.SearchStoreId != 1)
            {
                ssModels = _pictureDisplayService.GetSlideshowsByTypeAndContentCategory(null, "Store", model.SearchStoreId)
                .Select(ss =>
                {
                    var slideshowModel = ss.ToModel();
                    slideshowModel.CollectionSystemName =
                        _pictureDisplayService.GetPictureLinkCollectionById(ss.PictureLinkCollectionId).SystemName;
                    return slideshowModel;
                })
                .ToList();
            }
            else // model.SearchStoreId == 1
            {
                ssModels = _pictureDisplayService.GetAllSlideshows()
                .Select(ss =>
                {
                    var slideshowModel = ss.ToModel();
                    slideshowModel.CollectionSystemName =
                        _pictureDisplayService.GetPictureLinkCollectionById(ss.PictureLinkCollectionId).SystemName;
                    return slideshowModel;
                })
                .ToList();
            }

            var gridModel = new GridModel<SlideshowModel>
            {
                Data = ssModels,
                Total = ssModels.Count
            };

            return new JsonResult
            {
                Data = gridModel
            };
        }

        public ActionResult CreateSlideshow()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            return View(PrepareSlideshowModel(new SlideshowModel()));
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult CreateSlideshow(SlideshowModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            PrepareSlideshowModel(model);

            try
            {
                if (ModelState.IsValid)
                {
                    var s = model.ToEntity();

                    _pictureDisplayService.InsertSlideshow(s);

                    return continueEditing ?
                        RedirectToAction("EditSlideshow", new { id = s.Id }) : RedirectToAction("ListSlideshows");
                }
            }
            catch (Exception e)
            {
                ErrorNotification(e);
            }
            return View(model);
        }

        public ActionResult EditSlideshow(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var s = _pictureDisplayService.GetSlideshowById(id);
            if (s == null)
                //No slideshow found with the specified id
                return RedirectToAction("ListSlideshows");

            var model = PrepareSlideshowModel(s.ToModel());

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult EditSlideshow(SlideshowModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            PrepareSlideshowModel(model);

            var s = _pictureDisplayService.GetSlideshowById(model.Id);
            if (s == null)
                //No forum group found with the specified id
                return RedirectToAction("ListSlideshows");

            if (ModelState.IsValid)
            {
                s = model.ToEntity(s);
                _pictureDisplayService.UpdateSlideshow(s);

                //SuccessNotification(_localizationService.GetResource(""));
                return continueEditing ? RedirectToAction("EditSlideshow", s.Id) : RedirectToAction("ListSlideshows");
            }

            //If we got this far, something failed, redisplay form
            return View(model);
        }

        [HttpPost]
        public ActionResult DeleteSlideshow(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var s = _pictureDisplayService.GetSlideshowById(id);
            if (s == null)
                //No slideshow found with the specified id
                return RedirectToAction("ListSlideshows");

            _pictureDisplayService.DeleteSlideshow(s);

            //SuccessNotification(_localizationService.GetResource(""));
            return RedirectToAction("ListSlideshows");
        }

        #endregion

        #region PictureLinkCollection
        public ActionResult ListPictureLinkCollections()
        {
            IPagedList<PictureLinkCollection> picturelinkCollections;
            picturelinkCollections = _pictureDisplayService.GetAllPictureLinkCollections(0, _adminAreaSettings.GridPageSize);

            var gridModel = new GridModel<PictureLinkCollectionModel>
            {
                Data = picturelinkCollections.Select(x => x.ToModel()),
                Total = picturelinkCollections.TotalCount
            };

            return View(gridModel);
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult ListPictureLinkCollections(GridCommand command)
        {
            IPagedList<PictureLinkCollection> picturelinkCollections;
            picturelinkCollections = _pictureDisplayService.GetAllPictureLinkCollections(0, _adminAreaSettings.GridPageSize);

            var gridModel = new GridModel<PictureLinkCollectionModel>
            {
                Data = picturelinkCollections.Select(x => x.ToModel()),
                Total = picturelinkCollections.TotalCount
            };

            return new JsonResult
            {
                Data = gridModel
            };
        }

        public ActionResult CreatePictureLinkCollection()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var model = new PictureLinkCollectionModel() { RelatedContentId = 0 };

            PreparePictureLinkCollectionModel(model);

            return View(model);
        }

        [HttpPost]
        public ActionResult CreatePictureLinkCollection(PictureLinkCollectionModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            PreparePictureLinkCollectionModel(model);

            try
            {
                if (ModelState.IsValid)
                {
                    var c = model.ToEntity();

                    _pictureDisplayService.InsertPictureLinkCollection(c);
                    SuccessNotification(_localizationService.GetResource("Admin.Media.PictureLink.CreatePictureLinkCollection"));

                    return RedirectToAction("EditPictureLinkCollection", new { id = c.Id });
                }
            }
            catch (Exception e)
            {
                ErrorNotification(e);
            }

            return View(model);
        }

        public ActionResult EditPictureLinkCollection(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var c = _pictureDisplayService.GetPictureLinkCollectionById(id);
            if (c == null)
                //No picturelink collection found with the specified id
                return RedirectToAction("ListSlideshows");

            var model = c.ToModel();
            PreparePictureLinkCollectionModel(model);
            if (model.AddPictureLinkModel == null)
                model.AddPictureLinkModel = new PictureLinkModel();

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult EditPictureLinkCollection(PictureLinkCollectionModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            PreparePictureLinkCollectionModel(model);

            var c = _pictureDisplayService.GetPictureLinkCollectionById(model.Id);
            if (c == null)
                //No picturelink collection found with the specified id
                return RedirectToAction("ListSlideshows");

            if (ModelState.IsValid)
            {
                c = model.ToEntity(c);
                _pictureDisplayService.UpdatePictureLinkCollection(c);

                //SuccessNotification(_localizationService.GetResource(""));
                return continueEditing ? RedirectToAction("EditPictureLinkCollection", c.Id) : RedirectToAction("ListSlideshows");
            }

            //If we got this far, something failed, redisplay form
            return View(model);
        }

        [HttpPost]
        public ActionResult DeletePictureLinkCollection(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var c = _pictureDisplayService.GetPictureLinkCollectionById(id);
            if (c == null)
                //No slideshow found with the specified id
                return RedirectToAction("ListSlideshows");

            _pictureDisplayService.DeletePictureLinkCollection(c);

            //SuccessNotification(_localizationService.GetResource(""));
            return RedirectToAction("ListSlideshows");
        }

        [HttpPost]
        public JsonResult _GetDropDownListContents(string RelatedContentCategory)
        {
            var contents = _pictureDisplayService.GetRelatedContantSelectListByCategoryName(RelatedContentCategory) ?? new List<SelectListItem>();
            return Json(contents, JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region PictureLinks
        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult ListPictureLinks(GridCommand command, int pictureLinkCollectionId = -1)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            IPagedList<PictureLink> picturelinks = pictureLinkCollectionId == -1 ? _pictureDisplayService.GetAllPictureLinks(command.Page - 1, _adminAreaSettings.GridPageSize) : _pictureDisplayService.GetPictureLinks(pictureLinkCollectionId, command.Page - 1, _adminAreaSettings.GridPageSize);

            var gridModel = new GridModel<PictureLinkModel>
            {
                Data = picturelinks.Select(x => x.ToModel()),
                Total = picturelinks.TotalCount
            };

            return new JsonResult
            {
                Data = gridModel
            };
        }

        [ValidateInput(false)]
        public ActionResult CreatePictureLink(String systemName, String displayText, int displayOrder, String url, String alt, int pictureId, bool visible, int collectionId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            if (String.IsNullOrEmpty(url))
            {
                return Json(new { Message = "Empty" }, JsonRequestBehavior.AllowGet);
            }

            var model = new PictureLinkModel()
            {
                SystemName = systemName,
                DisplayText = displayText,
                DisplayOrder = displayOrder,
                Url = url,
                Alt = alt,
                PictureId = pictureId,
                Visible = visible,
                CollectionId = collectionId
            };

            if (ModelState.IsValid)
            {
                var p = model.ToEntity();
                _pictureDisplayService.InsertPictureLink(p);

                return Json(new { Message = "Success" }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(new { Message = "Fail" }, JsonRequestBehavior.AllowGet);
            }

        }

        public ActionResult EditPictureLink(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageForums))
                return AccessDeniedView();

            var p = _pictureDisplayService.GetPictureLinkById(id);
            if (p == null)
                //No forum found with the specified id
                return RedirectToAction("ListSlideshows");

            var model = p.ToModel();

            model = PreparePictureLinkModel(model);

            return View(model);
        }

        //
        // POST: /Media/Edit/5

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult EditPictureLink(PictureLinkModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageForums))
                return AccessDeniedView();

            var p = _pictureDisplayService.GetPictureLinkById(model.Id);
            if (p == null)
                //No forum found with the specified id
                return RedirectToAction("ListSlideshows");

            if (ModelState.IsValid)
            {
                p = model.ToEntity(p);
                _pictureDisplayService.UpdatePictureLink(p);

                //SuccessNotification(_localizationService.GetResource(""));
                return continueEditing ? RedirectToAction("EditForum", p.Id) : RedirectToAction("ListSlideshows");
            }

            //If we got this far, something failed, redisplay form
            model = PreparePictureLinkModel(model);
            return View(model);
        }

        [HttpPost]
        public ActionResult DeletePictureLink(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageForums))
                return AccessDeniedView();

            var p = _pictureDisplayService.GetPictureLinkById(id);
            if (p == null)
                //No forum found with the specified id
                return RedirectToAction("ListSlideshows");

            _pictureDisplayService.DeletePictureLink(p);

            //SuccessNotification(_localizationService.GetResource(""));
            return RedirectToAction("ListSlideshows");
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult PictureList(GridCommand command, int collectionId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return AccessDeniedView();

            var c = _pictureDisplayService.GetPictureLinkCollectionById(collectionId);
            if (c == null)
                //No picturelink collection found with the specified id
                return RedirectToAction("ListSlideshows");

            var plCollectionModel = c.PictureLinks
                .Select(x =>
                {
                    return new PictureLinkModel()
                    {
                        Id = x.Id,
                        SystemName = x.SystemName,
                        PictureId = x.PictureId,
                        Url = x.Url,
                        DisplayOrder = x.DisplayOrder,
                        DisplayText = x.DisplayText,
                        Alt = x.Alt,
                        Visible = x.Visible,
                        CollectionId = collectionId
                    };
                })
                .ToList();

            var model = new GridModel<PictureLinkModel>
            {
                Data = plCollectionModel,
                Total = plCollectionModel.Count
            };

            BuildPictureLinkModel(model);

            return new JsonResult
            {
                Data = model
            };
        }

        private void BuildPictureLinkModel(GridModel<PictureLinkModel> gridModel)
        {
            if (gridModel.Data == null) return;

            var data = gridModel.Data;
            IList<PictureLinkModel> links = new List<PictureLinkModel>();
            foreach (var item in data.Where(d => d.Visible).OrderBy(d => d.DisplayOrder).ToList())
            {
                item.ImageUrl = _pictureService.GetPictureUrl(item.PictureId, 300);
                links.Add(item);
            }

            gridModel.Data = links;
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult PictureListUpdate(PictureLinkModel model, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageForums))
                return AccessDeniedView();

            var p = _pictureDisplayService.GetPictureLinkById(model.Id);
            if (p == null)
                //No forum found with the specified id
                return RedirectToAction("ListSlideshows");

            p.SystemName = model.SystemName;
            p.DisplayOrder = model.DisplayOrder;
            p.DisplayText = model.DisplayText;
            p.Alt = model.Alt;
            p.Visible = model.Visible;

            _pictureDisplayService.UpdatePictureLink(p);

            return PictureList(command, p.CollectionId);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult PictureListDelete(int id, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageForums))
                return AccessDeniedView();

            var p = _pictureDisplayService.GetPictureLinkById(id);
            if (p == null)
                //No forum found with the specified id
                return RedirectToAction("ListSlideshows");

            _pictureDisplayService.DeletePictureLink(p);

            //delete image
            DeleteImage(p.PictureId);

            return PictureList(command, p.CollectionId);
        }

        private void DeleteImage(int pid)
        {
            if (pid <= 0) return;

            //删除image
            var picture = _pictureService.GetPictureById(pid);
            if (picture != null)
            {
                _pictureService.DeletePicture(picture);
            }
        }

        #endregion

        #region Helper

        [NonAction]
        protected SlideshowModel PrepareSlideshowModel(SlideshowModel model)
        {
            var collections = _pictureDisplayService.GetAllPictureLinkCollectionsByType(PictureDisplayType.Slideshow).ToList();
            collections.ForEach(c =>
                model.PicturelinkCollections.Add(
                new SelectListItem()
                {
                    Text = c.SystemName,
                    Value = c.Id.ToString(),
                    Selected = model.PictureLinkCollectionId == c.Id
                }));

            if (model.TypeOptions == null)
            {
                model.TypeOptions = new List<SelectListItem>();

                foreach (SlideshowType opt in Enum.GetValues(typeof(SlideshowType)))
                {
                    if (opt != SlideshowType.None)
                    {
                        model.TypeOptions.Add(
                            new SelectListItem()
                            {
                                Text = opt.ToString(),
                                Value = opt.ToString(),
                                Selected = model.Type == opt
                            });
                    }
                }
            }
            else
            {
                foreach (var item in model.TypeOptions)
                {
                    if (item.Selected)
                    {
                        SlideshowType selectedType = SlideshowType.None;
                        Enum.TryParse<SlideshowType>(item.Value, out selectedType);
                        model.Type = selectedType;
                    }
                }
            }

            return model;
        }

        [NonAction]
        protected void PreparePictureLinkCollectionModel(PictureLinkCollectionModel model)
        {
            // PictureDisplayTypeOptions should be rendered to mutiple check box
            if (model.PictureDisplayTypeOptions == null)
            {
                model.PictureDisplayTypeOptions = new List<PictureDisplayType>();

                foreach (PictureDisplayType opt in Enum.GetValues(typeof(PictureDisplayType)))
                {
                    if (opt != PictureDisplayType.None)
                        model.PictureDisplayTypeOptions.Add(opt);
                }
            }

            if (model.SelectedPictureDisplayTypeOptions != null && model.SelectedPictureDisplayTypeOptions.Length > 0)
            {
                model.PictureDisplayType = PictureDisplayType.None;
                foreach (var t in model.SelectedPictureDisplayTypeOptions)
                {
                    model.PictureDisplayType |= t;
                }
            }

            if (model.RelatedContentCategories == null)
            {
                model.RelatedContentCategories = _pictureDisplayService.GetAllRelatedContentCategoryNames()
                    .Select(cn => new SelectListItem() { Text = cn, Value = cn, Selected = (model.RelatedContentCategory == cn) })
                    .ToList();
            }

            if (model.RelatedContents == null && model.RelatedContentCategory != null)
            {
                model.RelatedContents = _pictureDisplayService.GetRelatedContantSelectListByCategoryName(
                    model.RelatedContentCategory,
                    model.RelatedContentId);
            }
        }

        [NonAction]
        protected PictureLinkModel PreparePictureLinkModel(PictureLinkModel model)
        {
            if (model.PicturelinkCollections.Count == 0)
            {
                var collections = _pictureDisplayService.GetAllPictureLinkCollections().ToList();
                collections.ForEach(c =>
                    model.PicturelinkCollections.Add(
                    new SelectListItem()
                    {
                        Text = c.SystemName,
                        Value = c.Id.ToString(),
                        Selected = model.CollectionId == c.Id
                    }));
            }

            if (model.Locales.Count == 0)
            {
                this.AddLocales<PictureLinkLocalizedModel>(this._languageService, model.Locales);
            }

            return model;
        }

        [NonAction]
        protected void SavePictureLink(PictureLink pictureLink, PictureLinkModel pictureLinkModel)
        {
            foreach (PictureLinkLocalizedModel m in pictureLinkModel.Locales)
            {
                _localizedEntityService.SaveLocalizedValue(pictureLink, p => p.DisplayText, m.DisplayText, m.LanguageId);
                _localizedEntityService.SaveLocalizedValue(pictureLink, p => p.Alt, m.Alt, m.LanguageId);
                _localizedEntityService.SaveLocalizedValue(pictureLink, p => p.Url, m.Url, m.LanguageId);
            }
        }

        #endregion
    }
}
